package tsg.graphic;

import java.util.Stack;

import tsg.shape.Polygon;
import tsg.shape.Rectangle;


public abstract class Graphics 
{
	/**
	 * 
	 * @param rectangle
	 * @param parentGraphics
	 */
	protected Graphics(Rectangle rectangle, Graphics parentGraphics)
	{
		this.setParentGraphics(parentGraphics);
	}
	
	/**
	 * 
	 * @return
	 */
	public Rectangle getDirtyRegion()
	{
		return _dirtyRegion;
	}
	
	/**
	 * 
	 * @param dirtyRegion
	 */
	public void setDirtyRegion(Rectangle dirtyRegion)
	{
		_dirtyRegion = dirtyRegion;
	}
	
	/**
	 * 
	 * @param rectangle
	 * @param parentGraphics
	 * @return
	 */
	public abstract Graphics createSubGraphics(Rectangle rectangle, Graphics parentGraphics);
	
	/**
	 * 
	 * @return
	 */
	protected Graphics getParentGraphics()
	{
		return _parentGraphics;
	}
	
	/**
	 * 
	 * @return
	 */
	protected Graphics getChildGraphics()
	{
		return _childGraphics;
	}
	
	/**
	 * 
	 * @return
	 */
	public Rectangle getRectangle()
	{
		return _rectangle;
	}
	
	/**
	 * 
	 * @param rectangle
	 */
	protected void setRectangle(Rectangle rectangle)
	{
		_rectangle = rectangle;
	}
	
	/**
	 * 
	 * @param parentGraphics
	 */
	protected void setParentGraphics(Graphics parentGraphics)
	{
		_parentGraphics = parentGraphics;
	}
	
	/**
	 * 
	 * @param childGraphics
	 */
	protected void setChildGraphics(Graphics childGraphics)
	{
		_childGraphics = childGraphics;
	}
	
	
	/**
	 * 
	 * @param x
	 * @param y
	 * @param width
	 * @param height
	 * @param startAngle
	 * @param arcAngle
	 */
	public abstract void drawArc (int x, int y, int width, int height, int startAngle, int arcAngle);
	
	/**
	 * 
	 * @param x
	 * @param y
	 * @param width
	 * @param height
	 * @param startAngle
	 * @param arcAngle
	 */
	public abstract void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle);
	                                         
	/**
	 * 
	 * @param x
	 * @param y
	 * @param width
	 * @param height
	 */
	public abstract void drawOval(int x, int y, int width, int height);
	
	/**
	 * 
	 * @param x
	 * @param y
	 * @param width
	 * @param height
	 */
	public abstract void fillOval(int x, int y, int width, int height);
	                                         
	/**
	 * 
	 * @param polygon
	 */
	public abstract void drawPolygon(Polygon polygon);
	
	/**
	 * 
	 * @param polygon
	 */
	public abstract void fillPolygon(Polygon polygon);
	                                         
	/**
	 * 
	 * @param x
	 * @param y
	 * @param width
	 * @param height
	 */
	public abstract void drawRectangle(int x, int y, int width, int height);
	
	/**
	 * 
	 * @param x
	 * @param y
	 * @param width
	 * @param height
	 */
	public abstract void fillRectangle(int x, int y, int width, int height);
	                     
	
	/**
	 * 
	 * @param x
	 * @param y
	 * @param width
	 * @param height
	 * @param arcWidth
	 * @param arcHeight
	 */
	public abstract void drawRoundRectangle(int x, int y, int width, int height, int arcWidth, int arcHeight);
	
	/**
	 * 
	 * @param x
	 * @param y
	 * @param width
	 * @param height
	 * @param arcWidth
	 * @param arcHeight
	 */
	public abstract void fillRoundRectangle(int x, int y, int width, int height, int arcWidth, int arcHeight);
	                     
	/**
	 * 
	 * @param image
	 * @param x
	 * @param y
	 */
	public abstract void drawImage(Image image, int x, int y);
	
	/**
	 * 
	 * @param image
	 * @param x
	 * @param y
	 * @param imageRectangle
	 */
	public abstract void drawImage(Image image, int x, int y, Rectangle imageRectangle);
	                                         
	
	/**
	 * 
	 * @param x1
	 * @param y1
	 * @param x2
	 * @param y2
	 */
	public abstract void drawLine(int x1, int y1, int x2, int y2);
	
	/**
	 * 
	 * @param xPoints
	 * @param yPoints
	 * @param nPoints
	 */
	public abstract void drawPolyline(int[] xPoints, int[] yPoints, int nPoints);
	                                         
	
	/**
	 * 
	 * @param str
	 * @param x
	 * @param y
	 */
	public abstract void drawString(String str, int x, int y);
	                                         
	           
	/**
	 * 
	 * @return
	 */
	public Color getColor()
	{
		return _color;
	}
	
	/**
	 * 
	 * @param color
	 */
	public void setColor(Color color)
	{
		_color = color;
	}
	                           
	
	/**
	 * 
	 * @return
	 */
	public Font getFont()
	{
		return _font;
	}
	
	/**
	 * 
	 * @param font
	 */
	public void setFont(Font font)
	{
		_font = font;
	}
	                           
	
	/**
	 * 
	 * @param x
	 * @param y
	 */
	public abstract void translate(int x, int y);
	
	
	
	/**
	 * TODO: I don't know that this does any good what so ever
	 */
	public void pushContext()
	{
		_contextStack.add(new GraphicsContext(_rectangle, _font, _color));
		
		_rectangle = new Rectangle(0, 0, _rectangle.getWidth(), _rectangle.getHeight());
	}
	
	
	/**
	 * 
	 */
	public void popContext()
	{
		GraphicsContext context = _contextStack.pop();
		
		_rectangle 	= context.getRectangle();
		_font		= context.getFont();
		_color		= context.getColor();
	}
	
	
	private Graphics 				_parentGraphics 	= null;
	private Graphics 				_childGraphics 		= null;
	private Rectangle				_rectangle			= null;
	private Rectangle				_dirtyRegion		= null;
	private Font					_font				= null;
	private Color					_color				= null;
	private Stack<GraphicsContext>	_contextStack		= new Stack<GraphicsContext>();
}
